from concurrent.futures import ThreadPoolExecutor, TimeoutError, as_completed
import threading, queue, time, random


msg_queue = queue.Queue()


def send(i):
    if i == 3:
        raise ValueError("boom")
    time.sleep(random.uniform(1.1, 3))
    msg_queue.put(f"send {i} at {time.time()}")
    return i


def receive():
    while True:
        try:
            msg = msg_queue.get()
            print("receive:", msg)

        except queue.Empty:
            print("queue is empty")
            break


with ThreadPoolExecutor(max_workers=1) as pool:
    print("start receive thread")
    pool.submit(receive)


with ThreadPoolExecutor(max_workers=4) as pool:
    print("start send thread")
    futs = [pool.submit(send, i) for i in range(10)]

    try:
        for fut in as_completed(futs):
            print(f"{fut.result()} done at {time.time()}")
    except TimeoutError:
        print("timeout")
    except Exception as e:
        print("error:", e)
    # 任务还没开始时可以取消
    # fut.cancel()

time.sleep(30)
